import { useCallback, useEffect, useRef } from "react"
import { useDispatch, useSelector } from "react-redux"
import { setIsEnd } from "@/store/TokenStore"
/**工具软件  lodash */
import _ from 'loadsh'
import { MessageType, setMessageList, setAIMessageListByid } from "@/store/MessageStore"
import { setServiceInfo } from "@/store/ServiceInfoStore"
import { stateType } from "@/store"
import { getTokenLocal } from "@/untils"
import timeFormater from "time-formater";

enum ModeCode {
    HEARTBEAT = 'HEARTBEAT',
    MESSAGE = 'MSG',
    SYSTEM = 'SYSTEM'
}

enum heat_beat {
    time = 2 * 1000,
    timeout = 1 * 1000,
    reconnect = 10 * 1000
}


const useWebsocket = (wsurl: string, fn: any = null, setServicetype: any = null) => {
    const aimsg = useRef('')
    //操作redux
    const dispatch = useDispatch()
    //获取 serverInfo
    const ServerInfo = useSelector((state: stateType) => state.ServiceReducer)
    //用于深度监听比较
    const ServerInfoRef = useRef(ServerInfo)
    let ws = useRef<WebSocket | null>(null)
    //用于存储websocket对象
    //用于判读ws是否链接成功
    let websocketState = useRef<boolean>(false)
    //用于重连的时间对象
    let reconnectTimer: any = null
    useEffect(() => {
        if (!(_.isEqual(ServerInfoRef.current, ServerInfo))) {
            //在获取到有数据的客服消息的时候启动ws
            ServerInfoRef.current = ServerInfo
            // console.log('ServerInfoRef.current', ServerInfoRef.current)
            connectWebSocket()
        }
    }, [ServerInfo])

    const sendMsg = (data: any) => {
        data.token = getTokenLocal()
        ws.current?.send(JSON.stringify(data))
    }


    //初始化ws
    const init = useCallback(() => {
        if (!ws) return
        const { chatid, nickname, head, prologue } = ServerInfoRef.current
        ws.current?.addEventListener('open', () => {
            websocketState.current = true
            sendMsg({ "type": "CONNECT" })
            /**此处判断是AI还是人工客服 */
            // if (ServerInfoRef.current.chatid.includes('AI')) {
                
            // } else if (chatid.includes('KEFU')) {
            //     const PrologueMsgTips: MessageType = {
            //         id: new Date().getTime() + '_local',
            //         head,
            //         nickname,
            //         sendid: chatid,
            //         time: '2022-01-09',
            //         info: {
            //             type: 'text',
            //             value: `${nickname} 继续为您服务`
            //         }
            //     }
            //     dispatch(setMessageList(PrologueMsgTips))
            // }
            //此处应开启心跳模式
            // Startheartbeat(heat_beat.time)
        })
        //监听回收的信息
        ws.current?.addEventListener('message', (e) => {
            const data = JSON.parse(e.data)
           
            switch (data.type) {
                case ModeCode.MESSAGE:
                    /**内部要判断是否是AI发送的信息还是人工发送的信息 */
                    if (data.sendChatId.includes('AI')) {
                        const { content, time } = data
                        const { id, content: AIcontent, is_end } = JSON.parse(content)
                        aimsg.current += AIcontent
                        const PrologueMsgText: MessageType = {
                            id,
                            head,
                            nickname,
                            sendid: chatid,
                            time: timeFormater().format('YYYY-MM-DD HH:mm:ss'),
                            info: {
                                type: 'AI',
                                value: aimsg.current.replace('```', '')
                            }
                        }
                        dispatch(setIsEnd(is_end))
                        if (is_end) {
                            aimsg.current = ''
                        }
                        dispatch(setAIMessageListByid(PrologueMsgText))
                        fn && fn()
                    } else if (data.sendChatId.includes('KEFU')) {
                        const { content, time, sendChatId, id } = data
                        const { type, info } = JSON.parse(content)
                        const PrologueMsgText: MessageType = {
                            id: ServerInfoRef.current.id,
                            head: ServerInfoRef.current.head,
                            nickname: ServerInfoRef.current.nickname,
                            sendid: sendChatId,
                            time: timeFormater().format('YYYY-MM-DD HH:mm:ss'),
                            isdelete: 'null',
                            info: {
                                type: type,
                                value: info
                            }
                        }
                        dispatch(setMessageList(PrologueMsgText))
                        fn && fn()
                    }
                    break
                case ModeCode.SYSTEM:
                    const { content, type } = JSON.parse(data.content)
                    if (type === 'CONNECTED_KEFU_SUCCESS') {
                        const serverInfo = JSON.parse(content)
                        //设置超管的信息
                        dispatch(setServiceInfo(serverInfo))
                        const PrologueMsgText: MessageType = {
                            id: ServerInfoRef.current.id,
                            head: ServerInfoRef.current.head,
                            nickname: ServerInfoRef.current.nickname,
                            sendid: ServerInfoRef.current.sendChatId,
                            time: timeFormater().format('YYYY-MM-DD HH:mm:ss'),
                            isdelete: 'null',
                            info: {
                                type: 'text',
                                value: `成功接入人工客服`
                            }
                        }
                        dispatch(setMessageList(PrologueMsgText))
                        fn && fn()
                    } else if (type === 'CLOSE_SERVICE') {
                        console.log('监听关闭的客服服务消息',data)
                        setServicetype && setServicetype()
                    }


                case ModeCode.HEARTBEAT:
                    websocketState.current = true
                    console.log('心跳消息', websocketState.current)
                    break

            }
        })
        //监听ws关闭
        ws.current?.addEventListener('close', () => {
            websocketState.current = false
            console.log('ws关闭了链接')
            reconnectWebSocket()
        })
        //监听出错消息
        ws.current?.addEventListener('error', () => {
            console.log('ws关闭了链接', 'error')
            reconnectWebSocket()
        })
    }, [ws, ServerInfo])
    //开启心跳模式
    const Startheartbeat = (time: number) => {
        setTimeout(() => {
            console.log('开启心跳')
            ws.current?.send(JSON.stringify({
                type: ModeCode.HEARTBEAT,
                msg: new Date()
            }))
            WattingServing()
        }, time);
    }
    //监听服务延时判断心跳是否停止

    const WattingServing = useCallback(() => {
        websocketState.current = false
        setTimeout(() => {
            console.log('websocketStatewebsocketStatewebsocketState', websocketState.current)
            if (websocketState.current) {
                Startheartbeat(heat_beat.time)
                return
            }

            try {
                ws.current?.close()
            } catch {
            }
            //启动重启服务
            reconnectWebSocket()
        }, heat_beat.timeout);
    }, [websocketState])

    //重连websocket
    const reconnectWebSocket = () => {
        console.log(!ws.current, (ws.current && reconnectTimer))
        reconnectTimer = setTimeout(() => {
            if (!ws.current) {
                connectWebSocket()
            }

            if (ws.current && reconnectTimer) {
                clearTimeout(reconnectTimer)
                reconnectTimer = null
                connectWebSocket()
            }
        }, heat_beat.reconnect);
    }

    //用户链接ws
    const connectWebSocket = useCallback(() => {
        if (ws.current) { return }
        ws.current = new WebSocket(wsurl)
        init()
    }, [ws, ServerInfo])

    const closConnect = useCallback(() => {
        ws.current?.close()
        websocketState.current = false
        clearTimeout(reconnectTimer)
    }, [ws])

    return {
        sendMsg,
        closConnect
    }
}

export default useWebsocket